home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / SERVER / Server.C < prev    next >
C/C++ Source or Header  |  1990-12-06  |  11KB  |  511 lines

  1. #include <stdio.h>
  2.  
  3. #include "String.h"
  4. #include "Error.h"
  5. #include "SunSystem.h"
  6. #include "sunsockets.h"
  7. #include "SunWindowPort.h"
  8. #include "SunBitmap.h"
  9. #include "SunFont.h"
  10. #include "Server.h"
  11.  
  12. const int cMaxConnections= 32;
  13.  
  14. class Connection *connections[cMaxConnections];
  15. static class Connection *clipboard;
  16. static bool cachegood= FALSE;
  17. static struct Response cache;
  18. static char *bp;
  19.  
  20. //---- ServerSunPort -----------------------------------------------------------
  21.  
  22. class ServerSunPort: public SunWindowPort {
  23.     class Connection *connection;
  24. public:
  25.     ServerSunPort(Connection *c, void *p1, bool b1, bool b2)
  26.                         : SunWindowPort(0, p1, b1, b2)
  27.     { connection= c; }
  28.     void Send(Token *t);
  29. };
  30.  
  31. //---- dummies -----------------------------------------------------------------
  32.  
  33. class ClipBoard {
  34.     int dummy;
  35. public:
  36.     ClipBoard();
  37.     ~ClipBoard();
  38.     bool NotOwner();
  39.     char *GetBuf(int*);
  40. };
  41. ClipBoard::ClipBoard() {}
  42. ClipBoard::~ClipBoard() {}
  43. bool ClipBoard::NotOwner() { return FALSE; }
  44. char *ClipBoard::GetBuf(int*) { return 0; }
  45. int gWindow;
  46. int gProgname;
  47. int _FileDialog_ShowInWindow;
  48. int _FileDialog__ctorFPC__;
  49.  
  50. //---- Connection --------------------------------------------------------------
  51.  
  52. const int MaxPorts      = 30,
  53.       MaxBitmaps    = 100,
  54.       MaxFonts      = 100;
  55.  
  56. class Connection : public SysEvtHandler {
  57.     FILE *ifp, *ofp;
  58.     int fd;
  59.     WindowPort *ports[MaxPorts];
  60.     Bitmap *bitmaps[MaxBitmaps];
  61.     Font *fonts[MaxFonts];
  62.     
  63. public:
  64.     Connection(int);
  65.     ~Connection();
  66.     
  67.     void CloseAll();
  68.     void Doit(struct Message*);  
  69.     
  70.     //---- I/O
  71.     int Read(void*, int);
  72.     void Write(void *vp, int l, bool flush= TRUE);
  73.     bool MoreMessages()
  74.     { return (bool) (available(ifp) >= sizeof(struct Message)); }
  75.     void Notify(SysEventCodes, int);
  76.     
  77.     //---- make new resources
  78.     int NewWindowPort(void *priv, bool b1, bool b2);
  79.     int NewBitmap(int l, Point p, u_short depth);
  80.     int NewFont(int fid, int ps, int face);
  81.     
  82.     //---- accessing
  83.     WindowPort *MapPort(int i)
  84.     { return (i<0 || i>=MaxPorts) ? 0 : ports[i]; }
  85.     Bitmap *MapBitmap(int i)
  86.     { return (i<0 || i>=MaxBitmaps) ? 0 : bitmaps[i]; }
  87.     Font *MapFont(int i)
  88.     { return (i<0 || i>=MaxFonts) ? 0 : fonts[i]; }
  89. };
  90.  
  91. void ServerSunPort::Send(Token *t)
  92. {
  93.     if (state == eWsShown && t && t->Code != eEvtNone && t->Code != eEvtIdle) {
  94.     struct Response rp;
  95.     
  96.     rp.port= (WindowPort*) privdata;
  97.     rp.t= *t;
  98.     connection->Write(&rp, sizeof(struct Response));
  99.     }
  100. }
  101.  
  102. Connection::Connection(int f) : SysEvtHandler(f)
  103. {
  104.     fd= f;
  105.     gSystem->AddFileInputHandler(this);
  106.     ifp= fdopen(f, "r");
  107.     ofp= fdopen(f, "w");
  108.     connections[f]= this;
  109. }
  110.  
  111. Connection::~Connection()
  112. {
  113.     CloseAll();
  114.     if (ifp)
  115.     fclose(ifp);
  116.     if (ofp)
  117.     fclose(ofp);
  118.     connections[fd]= 0;
  119. }
  120.     
  121. void Connection::Notify(SysEventCodes, int)
  122. {
  123.     struct Message m;
  124.     
  125.     do {
  126.     if (Read(&m, sizeof(struct Message))) 
  127.         return;
  128.     Doit(&m);
  129.     } while (MoreMessages());
  130. }
  131.  
  132. int Connection::Read(void *p, int l)
  133. {
  134.     if (fread((char*)p, l, 1, ifp) == 0) {
  135.     CloseAll();
  136.     Remove();
  137.     return TRUE;
  138.     }
  139.     return FALSE;
  140. }
  141.  
  142. void Connection::Write(void *vp, int l, bool flush)
  143. {
  144.     if (ofp) {
  145.     if (fwrite((char*)vp, l, 1, ofp) != 1)
  146.         SysError("Write", "");
  147.     if (flush)
  148.         fflush(ofp);
  149.     }
  150. }
  151.  
  152. void Connection::CloseAll()
  153. {
  154.     register int i;
  155.     
  156.     for (i= 0; i < MaxPorts; i++) {
  157.     if (ports[i]) {
  158.         if (ports[i]->state != eWsHidden)
  159.         ports[i]->DevHide1();
  160.         // ports[i]->Destroy();
  161.         ports[i]= 0;
  162.     }
  163.     }
  164.     for (i= 0; i < MaxBitmaps; i++)
  165.     SafeDelete(bitmaps[i]);
  166.     for (i= 0; i < MaxFonts; i++)
  167.     fonts[i]= 0;
  168. }
  169.  
  170. int Connection::NewWindowPort(void *priv, bool b1, bool b2)
  171. {
  172.     int id;
  173.     WindowPort *wport= new ServerSunPort(this, priv, b1, b2);
  174.     for (id= 0; id<MaxPorts; id++) {
  175.     if (ports[id] == 0) {
  176.         ports[id]= wport;
  177.         break;
  178.     }
  179.     }
  180.     if (id >= MaxPorts)
  181.     return -1;
  182.     return id;
  183. }
  184.  
  185. int Connection::NewBitmap(int l, Point p, u_short depth)
  186. {
  187.     int id;
  188.     Bitmap *bitmap;
  189.     short *slist= new short[(l+2)/2];
  190.     
  191.     Read(slist, l);
  192.     bitmap= new SunBitmap(p, (u_short*) slist, depth);
  193.     // bitmap= gWindowSystem->MakeBitmap(p, slist);
  194.     for (id= 0; id<MaxBitmaps; id++) {
  195.     if (bitmaps[id] == 0) {
  196.         bitmaps[id]= bitmap;
  197.         break;
  198.     }
  199.     }
  200.     if (id >= MaxBitmaps)
  201.     return -1;
  202.     return id;
  203. }
  204.  
  205. int Connection::NewFont(int fid, int ps, int face)
  206. {
  207.     int id;
  208.     Font *font;
  209.     
  210.     font= new_Font(fid, ps, face);
  211.     for (id= 0; id<MaxFonts; id++) {
  212.     if (fonts[id] == 0) {
  213.         fonts[id]= font;
  214.         break;
  215.     }
  216.     }
  217.     if (id >= MaxFonts)
  218.     return -1;
  219.     return id;
  220. }
  221.  
  222. void Connection::Doit(struct Message *m)
  223. {
  224.     byte *lp, c, list[MaxTextBatchCnt];
  225.     struct Response rp;
  226.     Font *font;
  227.     Bitmap *bitmap;
  228.     WindowPort *wport;
  229.     Point pos;
  230.     short d;
  231.     bool first;
  232.     register int i;
  233.     
  234.     rp.port= 0;
  235.     rp.t.Flags= m->seq; 
  236.     rp.t.At= 0;
  237.     rp.t.Pos.x= 0;
  238.     
  239.     switch (m->tag) {
  240.     case eMsgMakeWindow:
  241.     rp.t.Code= NewWindowPort((void*) m->i1, (bool) m->s1, (bool) m->s2);
  242.     Write(&rp, sizeof(struct Response));
  243.     return;
  244.     
  245.     case eMsgMakeFont:
  246.     rp.t.Code= NewFont(m->s1, m->s2, m->s3);
  247.     rp.t.Pos.x= sizeof(Font)-sizeof(void*);
  248.     Write(&rp, sizeof(struct Response), FALSE);
  249.     Write((void*) ((u_long)MapFont(rp.t.Code)+sizeof(void*)), rp.t.Pos.x);
  250.     return;
  251.     
  252.     case eMsgMakeBitmap:
  253.     rp.t.Code= NewBitmap(m->s1, m->p1, m->s2);
  254.     Write(&rp, sizeof(struct Response));
  255.     return;
  256.     
  257.     case eMsgDelay:
  258.     Wait(m->i1);
  259.     Write(&rp, sizeof(struct Response));
  260.     return;
  261.     }
  262.  
  263.     if ((wport= MapPort(m->id)) == 0) {
  264.     Error("Doit", "no such window (id:%d)", m->id);
  265.     return;
  266.     }
  267.     
  268.     GrSetPort(wport);
  269.     
  270.     switch (m->tag) {
  271.     
  272.     case eMsgShow:
  273.     wport->DevShow1(MapPort(m->i1), m->r1);
  274.     break;
  275.     
  276.     case eMsgTop:
  277.     wport->DevTop((bool) m->s1);
  278.     Write(&rp, sizeof(struct Response));
  279.     break;
  280.     
  281.     case eMsgHide:
  282.     wport->DevHide1();
  283.     break;
  284.     
  285.     case eMsgDestroy:
  286.     wport->Destroy();
  287.     ports[m->id]= 0;
  288.     break;
  289.     
  290.     case eMsgStrokeRect:
  291.     wport->DevStrokeRect(m->s1, m->i1, &m->r1);
  292.     break;
  293.     
  294.     case eMsgFillRect:
  295.     wport->DevFillRect(m->s1, &m->r1);
  296.     break;
  297.     
  298.     case eMsgStrokeRRect:
  299.     wport->DevStrokeRRect(m->s1, m->i1, &m->r1, m->p1);
  300.     break;
  301.     
  302.     case eMsgFillRRect:
  303.     wport->DevFillRRect(m->s1, &m->r1, m->p1);
  304.     break;
  305.     
  306.     case eMsgStrokeOval:
  307.     wport->DevStrokeOval(m->s1, m->i1, &m->r1);
  308.     break;
  309.     
  310.     case eMsgFillOval:
  311.     wport->DevFillOval(m->s1, &m->r1);
  312.     break;
  313.     
  314.     case eMsgStrokeWedge:
  315.     wport->DevStrokeWedge(m->s1, m->i1, m->s2, &m->r1, m->p1.x, m->p1.y);
  316.     break;
  317.     
  318.     case eMsgFillWedge:
  319.     wport->DevFillWedge(m->s1, &m->r1, m->p1.x, m->p1.y);
  320.     break;
  321.  
  322.     case eMsgClip:
  323.     wport->DevClip(m->r1, m->p1);
  324.     break;
  325.     
  326.     case eMsgSetRect:
  327.     wport->DevSetRect(&m->r1);
  328.     break;
  329.     
  330.     case eMsgGrab:
  331.     wport->DevGrab((bool) m->s1, (bool) m->s2);
  332.     break;
  333.     
  334.     case eMsgSetMousePos:
  335.     wport->DevSetMousePos(m->p1, (bool) m->s1);
  336.     break;
  337.     
  338.     case eMsgBell:
  339.     wport->DevBell((long)m->i1);
  340.     break;
  341.     
  342.     case eMsgStrokeLine:
  343.     wport->DevStrokeLine(m->s1, m->i1, &m->r1, m->s2, m->p1, m->p2);
  344.     break;
  345.     
  346.     case eMsgShowTextBatch:
  347.     Read(list, m->s2);
  348.     lp= list;
  349.     pos= m->p1;
  350.     first= TRUE;
  351.     font= gSysFont;
  352.     while (lp-list < m->s2) {
  353.         if ((c= *lp++) == '#') {
  354.         switch (c= *lp++) {
  355.         case '#':
  356.             break;
  357.         case 'x':
  358.             d= *lp++ << 8;
  359.             d|= *lp++;
  360.             pos.x+= d;
  361.             continue;
  362.         case 'y':
  363.             d= *lp++ << 8;
  364.             d|= *lp++;
  365.             pos.y+= d;
  366.             continue;
  367.         case 'f':
  368.             if ((font= MapFont((int)(*lp++))) == 0) {
  369.             Error("Doit", "no such font (id:%d)", (int)lp[-1]);
  370.             font= gSysFont;
  371.             }
  372.             continue;
  373.         }
  374.         }
  375.         wport->DevShowChar(font, gPoint0, c, first, pos);
  376.         first= FALSE;
  377.         pos.x+= font->Width(c);
  378.     }
  379.     wport->DevShowTextBatch(m->s1, &m->r1, m->p1);
  380.     break;
  381.     
  382.     case eMsgShowBitmap:
  383.     if ((bitmap= MapBitmap(m->i1)) == 0) {
  384.         Error("Doit", "no such bitmap (id:%d)", m->i1);
  385.         return;
  386.     }
  387.     wport->DevShowBitmap(m->s1, &m->r1, bitmap);
  388.     break;
  389.     
  390.     case eMsgResetClip:
  391.     wport->DevResetClip();
  392.     break;
  393.     
  394.     case eMsgGiveHint:
  395.     if (m->s2)
  396.         Read(list, m->s2);
  397.     wport->DevGiveHint(m->s1, m->s2, list);
  398.     break;
  399.     
  400.     case eMsgScrollRect:
  401.     wport->DevScrollRect(m->r1, m->p1);
  402.     Write(&rp, sizeof(struct Response));
  403.     break;
  404.     
  405.     case eMsgSetCursor:
  406.     wport->DevSetCursor((GrCursor)m->s1);
  407.     break;
  408.  
  409.     case eMsgHaveClipboard:
  410.     clipboard= this;
  411.     rp.t.Code= eMsgNotOwner;
  412.     for (i= 0; i < cMaxConnections; i++)
  413.         if (connections[i] && connections[i] != this)
  414.         connections[i]->Write(&rp, sizeof(struct Response));
  415.     SafeDelete(bp);
  416.     cachegood= FALSE;
  417.     break;
  418.     
  419.     case eMsgGetClipboard:
  420.     if (clipboard) {
  421.         if (! cachegood) {
  422.         clipboard->Write(&m, sizeof(struct Response));
  423.         clipboard->Read(&cache, sizeof(struct Response));
  424.         SafeDelete(bp);
  425.         bp= new char[rp.t.Pos.x];
  426.         clipboard->Read(bp, rp.t.Pos.x);
  427.         cachegood= TRUE;
  428.         }
  429.         Write(&cache, sizeof(struct Response), FALSE);
  430.         Write(bp, rp.t.Pos.x);
  431.     }
  432.     break;
  433.  
  434.     default:
  435.     Error("Doit", "unknown request (tag:%d)", m->tag);
  436.     break;
  437.     }
  438. }
  439.  
  440. //---- SunServerSystem ---------------------------------------------------------
  441.  
  442. class SunServerSystem: public SunSystem {
  443. public:
  444.     SunServerSystem()
  445.     { }
  446.     bool Init();
  447. };
  448.  
  449. //---- AcceptHandler -----------------------------------------------------------
  450.  
  451. class AcceptHandler : public SysEvtHandler {
  452. public:
  453.     AcceptHandler(int r) : SysEvtHandler(r)
  454.     { }
  455.     void Notify(SysEventCodes, int);
  456. };
  457.  
  458. void AcceptHandler::Notify(SysEventCodes, int)
  459. {    
  460.     int msgsock= accept(GetResourceId(), 0, 0);
  461.     if (msgsock < 0) {
  462.     SysError("Notify", "");
  463.     return;
  464.     }
  465.     new Connection(msgsock);
  466. }
  467.  
  468. //---- SunServerSystem ---------------------------------------------------------
  469.  
  470. bool SunServerSystem::Init()
  471. {
  472.     int sock= -1;
  473.     
  474.     if (SunSystem::Init())
  475.     return TRUE;
  476.     
  477.     if ((sock= TcpService(SERVICENAME)) >= 0)
  478.     AddFileInputHandler(new AcceptHandler(sock));
  479.     
  480.     if ((sock= UnixService(SERVERNAME)) >= 0)
  481.     AddFileInputHandler(new AcceptHandler(sock));
  482.     
  483.     if (sock < 0) {
  484.     Warning("SunServerSystem::Init", "no socket found");
  485.     return FALSE;
  486.     }
  487.     
  488.     cerr << "server ready\n";
  489.     return FALSE;
  490. }
  491.  
  492. //---- Main ---------------------------------------------------------------------
  493.  
  494. main()
  495. {
  496.     extern WindowSystem *NewSunWindowSystem();
  497.  
  498.     gSystem= new SunServerSystem();
  499.     if (gSystem->Init()) {
  500.     Error("ONENTRY", "can't init operating system");
  501.     _exit(1);
  502.     }
  503.     gWindowSystem= NewSunWindowSystem();
  504.     if (gWindowSystem == 0)
  505.     _exit(1);
  506.     gWindowSystem->Init();
  507.     gSystem->Control();
  508.     SafeDelete(gSystem);
  509.     SafeDelete(gWindowSystem);
  510. }
  511.